package cn.trinea.android.common.util;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.widget.ImageView;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Locale;

/**
 * @description: 文件处理工具类
 * @author: oushuhua
 */
public class FileUtils {
    public static boolean saveFile(String content, String filePath, String fileName) {
        if (!TextUtils.isEmpty(content)) {
            return saveFile(content.getBytes(), filePath, fileName);
        }
        return false;
    }

    /**
     * 获取拍照相片存储文件
     * @param context
     * @return
     */
    public static File createFile(Context context){
        File file;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            String timeStamp = String.valueOf(new Date().getTime());
            file = new File(Environment.getExternalStorageDirectory() +
                    File.separator + timeStamp+".jpg");
        }else{
            File cacheDir = context.getCacheDir();
            String timeStamp = String.valueOf(new Date().getTime());
            file = new File(cacheDir, timeStamp+".jpg");
        }
        return file;
    }

    /**
     * 指定文件名称保存文本内容到SD卡
     * saveFile
     *
     * @param bytes
     * @param filePath
     * @param fileName
     * @return boolean
     * <p>
     * 841306
     * @since 1.0.0
     */
    public static boolean saveFile(byte[] bytes, String filePath, String fileName) {
        FileOutputStream output = null;
        try {
            if (bytes != null) {
                File filesDir = new File(filePath);
                filesDir.mkdirs();
                File file = new File(filePath, fileName);
                file.createNewFile();
                output = new FileOutputStream(file);
                output.write(bytes);
                output.flush();
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null)
                    output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 获取本地图片
     * getLoacalBitmap
     *
     * @param url
     * @return Bitmap
     */
    public static Bitmap getLoacalBitmap(String url) {
        try {
            FileInputStream fis = new FileInputStream(url);
            return BitmapFactory.decodeStream(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }


    // 位图回收
    public static void releaseImageViewResouce(ImageView imageView) {
        if (imageView == null) return;
        Drawable drawable = imageView.getDrawable();
        if (drawable != null && drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }
    }

    /**
     * 读取assets中的图片
     * getImageFromAssetsFile
     *
     * @param context
     * @param fileName
     * @return Bitmap
     */
    public static Bitmap getImageFromAssetsFile(Context context, String fileName) {
        Bitmap image = null;
        AssetManager am = context.getResources().getAssets();
        try {
            InputStream is = am.open(fileName);
            image = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return image;

    }

    /**
     * 判断文件是否存在， true表示存在，false表示
     * isFileExits
     *
     * @param filePath
     * @return boolean
     */
    public static boolean isFileExits(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return true;
        }
        return false;
    }

    /**
     * 保存图片到本地
     * saveFile
     *
     * @param bitmap
     * @param filePath
     */
    public static boolean saveBitmapFile(Bitmap bitmap, String filePath) {

        if (bitmap == null)
            return false;
        OutputStream output = null;

        try {
            File file = new File(filePath);
            if (file.exists()) {
                output = new FileOutputStream(file);

                CompressFormat format = CompressFormat.PNG;
                String tempFileName = filePath.toLowerCase(Locale.getDefault());
                if (".jpg".endsWith(tempFileName)) {
                    format = CompressFormat.JPEG;
                } else if (".png".endsWith(tempFileName)) {
                    format = CompressFormat.PNG;
                }

                bitmap.compress(format, 100, output);
                output.flush();
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null)
                    output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 保存字符串到本地
     * saveFile
     *
     * @param content
     * @param filePath
     * @return boolean
     */
    public static boolean saveStrFile(String content, String filePath) {
        if (!TextUtils.isEmpty(content)) {
            return saveStrFile(content.getBytes(), filePath);
        }
        return false;
    }

    /**
     * 保存字符串到本地
     *
     * @return
     */
    public static boolean saveStrFile(byte[] bytes, String filePath) {
        FileOutputStream output = null;
        try {
            if (bytes != null) {
                File file = new File(filePath);
                output = new FileOutputStream(file);
                output.write(bytes);
                output.flush();
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null)
                    output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public static boolean saveFile(InputStream instream, String fileName, String filePath) {
        File files = new File(filePath);
        FileOutputStream buffer = null;
        File file = new File(files.getAbsoluteFile(), fileName);
        try {
            file.createNewFile();
            if (instream != null) {
                buffer = new FileOutputStream(file);
                byte[] tmp = new byte[1024];
                int length = 0;
                while ((length = instream.read(tmp)) != -1) {
                    buffer.write(tmp, 0, length);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (instream != null)
                    instream.close();
                if (buffer != null) {
                    buffer.flush();
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 保存数据流到本地
     * saveFile
     *
     * @param instream
     * @param filePath
     * @return boolean
     */
    public static boolean saveFile(InputStream instream, String filePath) {

        File file = new File(filePath);
        FileOutputStream buffer = null;

        try {
            if (instream != null) {
                buffer = new FileOutputStream(file);
                byte[] tmp = new byte[1024];
                int length = 0;
                while ((length = instream.read(tmp)) != -1) {
                    buffer.write(tmp, 0, length);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (instream != null)
                    instream.close();
                if (buffer != null) {
                    buffer.flush();
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 读取文件
     * readFile
     *
     * @param filePath
     * @return String
     */
    public static String readFile(String filePath) {

        StringBuilder sb = new StringBuilder();
        try {
            FileInputStream fis = new FileInputStream(filePath);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 按照指定文本读取文件
     * readFile
     *
     * @param filePath
     * @param charset
     * @return String
     */
    public static String readFile(String filePath, String charset) {

        StringBuilder sb = new StringBuilder();
        try {
            FileInputStream fis = new FileInputStream(filePath);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis, charset));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 读取数据流生成的文本
     * readFileSdcard
     *
     * @param fileName
     * @return String
     */
    public static String readFileSdcard(String fileName) {
        String res = "";
        try {
            FileInputStream fin = new FileInputStream(fileName);
            int length = fin.available();
            byte[] buffer = new byte[length];
            fin.read(buffer);
            res = new String(buffer,"UTF-8");//EncodingUtils.getString(buffer, "UTF-8");
            fin.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 从resource的raw中读取文件数据
     *
     * @param context
     * @param resId
     * @return
     */
    public static InputStream getRawStream(Context context, int resId) {
        try {
            return context.getResources().openRawResource(resId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从resource的asset中读取文件字符串
     *
     * @param context
     * @param fileName
     * @return
     */
    public static String getAssetsString(Context context, String fileName) {
        try {
            return inputSteamToString(context.getResources().getAssets().open(fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从resource的asset中读取文件数据
     *
     * @param context
     * @param fileName
     * @return
     */
    public static InputStream getAssetsStream(Context context, String fileName) {
        try {
            return context.getResources().getAssets().open(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将byte[]转换成InputStream
     *
     * @param b
     * @return
     */
    public static InputStream Byte2InputStream(byte[] b) {
        ByteArrayInputStream bais = new ByteArrayInputStream(b);
        return bais;
    }

    /**
     * InputStream转换成byte[]
     * @return
     */
    public static byte[] InputStream2Bytes(InputStream instream) {
        byte bytes[] = null;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            byte[] tmp = new byte[1024];
            int length = 0;
            while ((length = instream.read(tmp)) != -1) {
                output.write(tmp, 0, length);
            }
            bytes = output.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (instream != null)
                    instream.close();
                if (output != null)
                    output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;

    }

    /**
     * 数据流转字符串
     * @return
     * @throws IOException
     */
    public static String inputSteamToString(InputStream instream) {
        String result = null;
        try {
            byte bytes[] = InputStream2Bytes(instream);
            result = new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除文件
     *
     * @param path
     * @return
     */
    public static boolean deleteFile(String path) {
        try {
            File file = new File(path);
            if (file.exists()) {
                file.delete();
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 得到文件名
     *
     * @param fileName
     * @param filePath
     * @return
     */
    public static String getFilePath(String fileName, String... filePath) {
        StringBuilder filebuilder = new StringBuilder();
        if (filePath != null) {
            for (String path : filePath) {
                filebuilder.append(path).append(File.separator);
            }
            File file = new File(filebuilder.toString());
            if (!file.exists()) {
                file.mkdirs();
            }
            filebuilder.append(fileName);
        }
        return filebuilder.toString();
    }

    /**
     * 从assets中拷贝文件到SD卡
     *
     * @param context
     * @param fileName
     * @param filePath
     */
    public static void assetsDataToSD(Context context, String fileName, String filePath) {
        try {
            InputStream myInput = context.getAssets().open(fileName);
            if (myInput != null) {
                saveFile(myInput, fileName, filePath);
            }
            myInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static String convertStreamToString(BufferedReader reader) {

        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 删除文件夹
     *
     */
    public static void deleteDirectory(File file) {
        if (file.isFile()) {
            file.delete();
            return;
        }

        File[] childFiles = file.listFiles();
        if (childFiles == null || childFiles.length == 0) {
            file.delete();
            return;
        }

        for (int i = 0; i < childFiles.length; i++) {
            deleteDirectory(childFiles[i]);
        }
        file.delete();
    }

    public static void deleteDirectory(String path) {
        File file = new File(path);
        deleteDirectory(file);
    }

    public static void savaToJson(JSONObject o, String filePath) {
        File file = new File(filePath);
        PrintStream out = null;
        try {
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            out = new PrintStream(new FileOutputStream(file));
            out.print(o.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 根据路径，文件名生成文件路径，路径不包含文件分隔符号，文件名不包含路径
     *
     * @return File
     */
    public static File CreateFile(String path, String filename) {
        // 判断文件夹是否存在
        // 如果不存在、则创建一个新的文件夹(一次创建多层目录，使用mkdirs()，不能使用mkdir())
        File f = new File(path);
        if (!f.exists()) {
            f.mkdirs();
        }
        File file = new File(path + File.separator + filename);
        // 如果目标文件已经存在
        if (file.exists() == false) {
            try {
                file.createNewFile(); // 创建新文件
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return file;
    }

    /**
     * 拷贝assets下的指定文件夹内容
     *
     * @param context
     * @param dirname
     * @throws IOException
     */
    public static void copyAssetDirToFiles(Context context, String dirname) throws IOException {
        File dir = new File(context.getFilesDir() + "/" + dirname);
        dir.mkdir();
        AssetManager assetManager = context.getAssets();
        String[] children = assetManager.list(dirname);
        for (String child : children) {
            child = dirname + '/' + child;
            String[] grandChildren = assetManager.list(child);
            if (0 == grandChildren.length)
                copyAssetFileToFiles(context, child);
            else
                copyAssetDirToFiles(context, child);
        }
    }

    public static void copyAssetFileToFiles(Context context, String filename) throws IOException {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = context.getAssets().open(filename);
            File of = new File(context.getFilesDir() + "/" + filename);
            of.createNewFile();
            out = new FileOutputStream(of);
            byte[] by = new byte[1024 * 4];
            int len = 0;
            while ((len = in.read(by, 0, by.length)) > 0) {
                out.write(by, 0, len);
                out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
            } catch (Exception e1) {

                e1.printStackTrace();
            }
        }
    }

    /**
     * 打开文件
     * 兼容7.0
     *
     * @param context     activity
     * @param file        File
     * @param contentType 文件类型如：文本（text/html）
     *                    当手机中没有一个app可以打开file时会抛ActivityNotFoundException
     */
    public static void startActionFile(Context context, File file, String contentType) throws ActivityNotFoundException {
        if (context == null) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);//增加读写权限
        intent.setDataAndType(getUriForFile(context, file), contentType);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }
    /**
     * 打开相机
     * 兼容7.0
     *
     * @param activity    Activity
     * @param file        File
     * @param requestCode result requestCode
     */
    public static void startActionCapture(Activity activity, File file, int requestCode) {
        if (activity == null) {
            return;
        }
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, getUriForFile(activity, file));
        activity.startActivityForResult(intent, requestCode);
    }


    public static Uri getUriForFile(Context context, File file) {
        if (context == null || file == null) {
            throw new NullPointerException();
        }
        Uri uri;
        if (Build.VERSION.SDK_INT >= 24) {
            uri = FileProvider.getUriForFile(context.getApplicationContext(), context.getPackageName()+".provider", file);
        } else {
            uri = Uri.fromFile(file);
        }
        return uri;
    }


}
